home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / db / esm-3.1 / esm-3 / usr / local / sm / src / serverlib / distr / serverActions.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-05  |  8.2 KB  |  328 lines

  1. /*
  2.  *   $RCSfile: serverActions.c,v $  
  3.  *   $Revision: 1.1.1.1 $  
  4.  *   $Date: 1996/05/04 21:55:41 $      
  5.  */ 
  6. /**********************************************************************
  7. * EXODUS Database Toolkit Software
  8. * Copyright (c) 1991 Computer Sciences Department, University of
  9. *                    Wisconsin -- Madison
  10. * All Rights Reserved.
  11. *
  12. * Permission to use, copy, modify and distribute this software and its
  13. * documentation is hereby granted, provided that both the copyright
  14. * notice and this permission notice appear in all copies of the
  15. * software, derivative works or modified versions, and any portions
  16. * thereof, and that both notices appear in supporting documentation.
  17. *
  18. * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
  19. * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.  
  20. * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  21. * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  22. *
  23. * The EXODUS Project Group requests users of this software to return 
  24. * any improvements or extensions that they make to:
  25. *
  26. *   EXODUS Project Group 
  27. *     c/o David J. DeWitt and Michael J. Carey
  28. *   Computer Sciences Department
  29. *   University of Wisconsin -- Madison
  30. *   Madison, WI 53706
  31. *
  32. *     or exodus@cs.wisc.edu
  33. *
  34. * In addition, the EXODUS Project Group requests that users grant the 
  35. * Computer Sciences Department rights to redistribute these changes.
  36. **********************************************************************/
  37.  
  38. #include "sysdefs.h"
  39. #include "ess.h"
  40. #include "checking.h"
  41. #include "trace.h"
  42. #include "error.h"
  43. #include "list.h"
  44. #include "pool.h"
  45. #include "tid.h"
  46. #include "io.h"
  47. #include "lock.h"
  48. #include "object.h"
  49. #include "msgdefs.h"
  50. #include "thread.h"
  51. #include "semaphore.h"
  52. #include "link.h"
  53. #include "lsn.h"
  54. #include "latch.h"
  55. #include "bf.h"
  56. #include "volume.h"
  57. #include "trans.h"
  58. #include "openlog.h"
  59. #include "logrecs.h"
  60. #include "logaction.h"
  61. #include "bitvec.h"
  62. #include "adminmsg.h"
  63. #include "trans_intfuncs.h"
  64. #include "trans_extfuncs.h"
  65. #include "lm_extfuncs.h"
  66. #include "log_extfuncs.h"
  67. #include "msg_funcs.h"
  68. #include "io_extfuncs.h"
  69. #include "trans_globals.h"
  70. #include "thread_globals.h"
  71. #include "admin_globals.h"
  72. #include "admin_funcs.h"
  73. #include "io_globals.h"
  74. #include "distr.h"
  75. #include "distr_globals.h"
  76. #include "distr_intfuncs.h"
  77.  
  78. /*
  79.  *    For write timing of log pages
  80.  */
  81. extern FOUR StatTotalTime_usec;
  82. extern FOUR StatPagesWritten;
  83. extern FOUR StatWriteCalls;
  84. extern FOUR    StatClientMsgs;
  85.  
  86. extern FILE *sm_ErrorStream;
  87.  
  88.  int
  89. serverPrepareTrans (
  90.     register TRANSREC    *transRec,
  91.     VOTE                *vote
  92. )
  93. {
  94.  
  95.     DIRTYPAGELOGINFO    *dirtyInfo = DirtyPageLogInfo;
  96.     int                    numDirtyPages;
  97.     LOGRECORDINFO        recordInfo;
  98.     FORCEMARK            forceMark;
  99.  
  100.     TRPRINT(TR_TRANS, TR_LEVEL_2, ("tid:%d", GETTID(transRec)));
  101.  
  102.     if (PrintExtraStats && StatPagesWritten > 0) {
  103.         fprintf(sm_ErrorStream, "PreCommit write times: time=%d #pages=%d #writeCalls=%d clientMsgs=%d\n", StatTotalTime_usec/1000, StatPagesWritten, StatWriteCalls, StatClientMsgs);
  104.         StatPagesWritten = StatWriteCalls = StatClientMsgs = StatTotalTime_usec = 0;
  105.     }
  106.  
  107.     /*
  108.      *    Temporarily make the transaction active in order to log 
  109.      *    page deallocations.
  110.      */
  111.     transRec->transState = T_ACTIVE;
  112.  
  113.     initializeList(&(transRec->pendingBitmapList));    
  114.      
  115.     /* 
  116.      *    deallocate all temporary files and pages 
  117.      *    Note: this can be done at prepare time because
  118.      *          it shall be done regardless of commit/abort 
  119.      */
  120.     deallocTempFilesPages(transRec);
  121.     /*
  122.      *    add all the pages in the all the files to be destroyed
  123.      *    to the list of pages to deallocate
  124.      */
  125.     if (transDeallocFilePages(transRec) != esmNOERROR) {
  126.         /* clean up dealloc info */
  127.         SM_ERROR(TYPE_CRASH, esmINTERNAL);    
  128.     }
  129.  
  130.     /*
  131.      *    Log all pending page deallocations
  132.      */
  133.     if (logTransDeallocPages(transRec, &(transRec->pendingBitmapList)) != esmNOERROR) {
  134.         /* 
  135.          *     For now, just crash, but we should really clean things up
  136.          *    and abort the transaction.  Clean-up is complicated by
  137.          *    the bitmap and volume header pages which are pinned with
  138.          *    pending operations.
  139.          */
  140.         SM_ERROR(TYPE_CRASH, esmINTERNAL);
  141.     }
  142.  
  143.     /*
  144.      *    Restore transaction to the quiesced state
  145.      */
  146.     transRec->transState = T_QUIESCE;
  147.  
  148.     /*
  149.      *    If the transaction generated some log records, make sure they
  150.      *    are flushed.
  151.      */
  152.     if (transRec->logRecordCount > 0)    {
  153.  
  154.         /*
  155.          *    Make sure only one thread is using the global
  156.          *    variable DirtyPageLogInfo at a time.
  157.          */
  158.         if (waitSemaphore(&DirtyPageLogInfoSemaphore)) {
  159.             SM_ERROR(TYPE_FATAL, esmINTERNAL);
  160.         }
  161.  
  162.         /*
  163.          *    Fill an array of information for all pages dirtied by
  164.          *    this transaction since the last checkpoint.
  165.          */
  166.         numDirtyPages = listDirtyTransPages(transRec, dirtyInfo);
  167.         PRINT_PROGRESS(("logging %d pages as dirty since last checkpoint\n", numDirtyPages));
  168.  
  169.         /*
  170.          *    Generate a log record containing the dirty page info
  171.          */
  172.         recordInfo.action       = 0;
  173.         recordInfo.type         = LOG_REC_TYPE_DIRTYPAGELIST;
  174.         recordInfo.imageCount   = 1;
  175.         recordInfo.actionPid    = NULL;
  176.         recordInfo.actionLRC    = NULL;
  177.         recordInfo.imageSize[0] = numDirtyPages * sizeof(DIRTYPAGELOGINFO);
  178.         recordInfo.imageData[0] = (char *) dirtyInfo;
  179.         recordInfo.nextUndoLSN  = NULL_LSN;
  180.         recordInfo.flags          = REDO_ONLY;
  181.  
  182.         /*
  183.          *  write the record to the log
  184.          */
  185.         if ((forceMark = writeNonTransLogRecord(&recordInfo, NULL, NOFLAGS)) < 0)  {
  186.             /* caller will abort */
  187.             signalSemaphore(&DirtyPageLogInfoSemaphore);
  188.             return(esmFAILURE);
  189.         }
  190.  
  191.         /*
  192.          *    Done with DirtyPageLogInfo
  193.          */
  194.         signalSemaphore(&DirtyPageLogInfoSemaphore); 
  195.  
  196.         /*
  197.          *    we must log the prepare record
  198.          */
  199.         if (server_LogPrepare(transRec, vote) < esmNOERROR) {
  200.             /* caller will abort */
  201.             return(esmFAILURE);
  202.         }
  203.  
  204.         TRPRINT(TR_DISTR|TR_TRANS, TR_LEVEL_2, 
  205.             ("server : wrote T_PREPARED : tid:%d", GETTID(transRec)));
  206.  
  207.         if (*vote == READVOTE) {
  208.             /*
  209.              *    read-only transaction 
  210.              *    forget it and return success
  211.              */
  212.              if (serverCommitTrans(transRec) != esmNOERROR) {
  213.                 SM_ERROR(TYPE_FATAL, esmINTERNAL);
  214.              }
  215.             return(esmNOERROR);
  216.         }
  217.  
  218.     } else if (!transRec->loggingOn) {
  219.         /*
  220.          *    Logging is turned off - return NOVOTE for now 
  221.          *    TODO: maybe allow this - will not be able to log
  222.          *          COMMIT though
  223.          */
  224.         *vote = NOVOTE;
  225.         SM_ERROR(TYPE_USER, esmLOGGINGOFF);
  226.         /* caller will abort */
  227.         return(esmFAILURE);
  228.  
  229.     } else {
  230.  
  231.         SM_ASSERT(LEVEL_3, LIST_EMPTY(&(transRec->clientDirtyList)));
  232.  
  233.         /*
  234.          *    read-only transaction 
  235.          *    forget it and return success
  236.          */
  237.          if (serverCommitTrans(transRec) != esmNOERROR) {
  238.             SM_ERROR(TYPE_FATAL, esmINTERNAL);
  239.          }
  240.     }
  241.  
  242.     return(esmNOERROR);
  243. }
  244.  
  245.  
  246.  
  247.  int
  248. serverCommitTrans (
  249.  
  250.     register TRANSREC    *transRec 
  251. )
  252. {
  253.     TRPRINT(TR_TRANS, TR_LEVEL_2, ("tid:%d", GETTID(transRec)));
  254.  
  255.     if (PrintExtraStats && StatPagesWritten > 0) {
  256.         fprintf(sm_ErrorStream, "PreCommit write times: time=%d #pages=%d #writeCalls=%d clientMsgs=%d\n", StatTotalTime_usec/1000, StatPagesWritten, StatWriteCalls, StatClientMsgs);
  257.         StatPagesWritten = StatWriteCalls = StatClientMsgs = StatTotalTime_usec = 0;
  258.     }
  259.  
  260. #ifdef DEBUG
  261.     if (DebugCrashLoc == 14)
  262.         admin_ShutServer(0);
  263. #endif DEBUG
  264.  
  265.     /*
  266.      *    we must log the commit record
  267.      */
  268.     if (server_LogCommit(transRec)  < esmNOERROR) {
  269.  
  270.         SM_ERROR(TYPE_CRASH, esmINTERNAL);    
  271.    
  272.     }
  273.     TRPRINT(TR_DISTR|TR_TRANS, TR_LEVEL_2, 
  274.             ("server : wrote T_COMMIT : tid:%d", GETTID(transRec)));
  275.  
  276.     /*
  277.      *  Perform all pending page deallocations
  278.      */
  279.     if (deallocTransPages(transRec, &(transRec->pendingBitmapList)) != esmNOERROR) {
  280.  
  281.         SM_ERROR(TYPE_FATAL, esmINTERNAL);
  282.     }
  283.  
  284.     SM_ASSERT(LEVEL_3, LIST_EMPTY(&(transRec->fileDeallocList)));
  285.     SM_ASSERT(LEVEL_3, LIST_EMPTY(&(transRec->pageDeallocList)));
  286.     SM_ASSERT(LEVEL_3, LIST_EMPTY(&(transRec->pendingBitmapList)));
  287.  
  288.     /*
  289.      *  Make sure all bitmaps are consistent after any
  290.      *  deallocation/allocation
  291.      */
  292.     SM_ASSERT(LEVEL_3, io_CheckAllVolumes() == esmNOERROR);
  293.  
  294.     /*
  295.      *    check to see if there are any log records
  296.      *    that are written for this transaction
  297.      */
  298.     if (transRec->lastLSN != 0)    {
  299.         /*
  300.          *    take the record off the log queue
  301.          */
  302.         removeLogList(transRec);
  303.     }
  304.  
  305.     /*
  306.      *    free all the locks
  307.      */
  308.     unlockAll(transRec, esmTRANSCOMMITTED);
  309.  
  310.     /*
  311.      *    free the structures
  312.      */
  313.     freeTransVolRecs(transRec);
  314.  
  315.     /*
  316.      *    give back the transaction record
  317.      *  reset the state to T_INACTIVE
  318.      */
  319.     freeTransRec(transRec);
  320.  
  321.     TotalCommits++;
  322.  
  323.     /*
  324.      *    return with success
  325.      */
  326.     return(esmNOERROR);
  327. }
  328.